import { createWriteStream, existsSync, mkdirSync } from 'fs'
import { join, extname } from 'path'
import { sms } from 'tencentcloud-sdk-nodejs'
import { BadRequestException } from '@nestjs/common'
import { nanoid } from 'nanoid'
import { SmsConstant } from '../constant'
// npm install --save flake-idgen  // 雪花算法
import * as FlakeId from 'flake-idgen'
// npm install --save biguint-format  // 格式化
import * as format from 'biguint-format'

/**
 * 随机验证码
 */
const randomCode = (): string => {
  // Math.floor返回小于或等于一个给定数字的最大整数
  // Math.random随机获得一个0-1之间的随机数
  return Math.floor(Math.random() * 1000000) + ''
}

/**
 * 发送短信验证码
 * @param phone
 */
export const sendCode = async (phone: string) => {
  // 验证码
  const code = randomCode()

  // 导入对应产品模块的client models。
  const smsClient = sms.v20190711.Client

  // 腾讯云
  const config = {
    credential: {
      /* 必填：腾讯云账户密钥对secretId，secretKey。
       * CAM密匙查询: https://console.cloud.tencent.com/cam/capi */
      secretId: SmsConstant.SECRET_ID,
      secretKey: SmsConstant.SECRET_KEY,
    },
    /* 必填：地域信息，可以直接填写字符串ap-guangzhou，或者引用预设的常量 */
    region: 'ap-guangzhou',
    profile: {
      // 域名
      httpProfile: {
        endpoint: 'sms.tencentcloudapi.com',
      },
    },
  }

  /* 实例化要请求产品(以sms为例)的client对象 */
  const client = new smsClient(config)

  const params = {
    // 手机号列表
    PhoneNumberSet: [86 + phone],
    // 验证码
    TemplateParamSet: [code],
    // 模板ID
    TemplateID: SmsConstant.TEMPLATE_ID,
    // SMS应用ID
    SmsSdkAppid: SmsConstant.SMS_SDK_APP_ID,
    // 签名
    Sign: SmsConstant.SIGN,
  }
  const { SendStatusSet } = await client.SendSms(params)
  if (SendStatusSet[0].Code === 'Ok') {
    return code
  }
  throw new BadRequestException('验证码获取频繁')
}

/**
 * 文件上传
 * @param file
 */
export const uploadFile = (file): string => {
  // 储存头像的目录
  const dir = join(__dirname, '..', 'uploads')
  // console.log(dir)
  // 验证目录是否存在
  if (!existsSync(dir)) {
    mkdirSync(dir)
  }
  // 文件名称【extname()缩短文件名称】
  const fileName = nanoid() + extname(file.originalname)
  // 文件存储的完整路径
  const path = join(dir, fileName)
  // 创建输出流对象
  const writeStream = createWriteStream(path)
  // 写文件数据
  writeStream.write(file.buffer)
  // 关闭流
  writeStream.close()

  return 'http://localhost:3000/' + fileName //[需要静态服务才能查找]
}

/**
 * 生成订单id
 */
export const snowflake = () => {
  // 递归【自己调自己】
  try {
    // 雪花算法
    const flakeId = new FlakeId({ epoch: 1300000000000 })
    // console.log(flakeId.next())
    // 格式化
    return format(flakeId.next())
  } catch (e) {
    snowflake()
  }
}
